package org.acsis.jee.services;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.acsis.covoiturage.services.ITrajetServices;
import org.acsis.covoiturage.shared.AlreadySubscribedException;
import org.acsis.covoiturage.shared.ITrajet;
import org.acsis.jee.dao.ClientDAO;
import org.acsis.jee.dao.DAOFactory;
import org.acsis.jee.dao.LieuDAO;
import org.acsis.jee.dao.TrajetDAO;
import org.acsis.jee.pojo.Client;
import org.acsis.jee.pojo.Lieu;
import org.acsis.jee.pojo.Trajet;
import org.acsis.jee.transfert.TrajetTransfert;
import org.acsis.jee.util.HibernateUtil;
import org.hibernate.NonUniqueObjectException;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class TrajetServices implements ITrajetServices{

	private DAOFactory dao = DAOFactory.getDAOFactory(DAOFactory.HIBERNATE);
	
	@Override
	public ITrajet ajouterTrajet(Date dateDepart, Long conducteur,
			String lieuDepart, String lieuArrivee, short nbPlaceRestantes,
			double prixPlace) {
		
		
		ClientDAO cdao = dao.getClientDAO();
		
		Client c = cdao.get(new Long(conducteur));

        LieuDAO ldao = dao.getLieuDAO();
        Session s = HibernateUtil.getCurrentSession();
		Transaction trx = s.beginTransaction();
        
        Lieu depart;
        if(!ldao.isExists(lieuDepart)){
        	depart = new Lieu(lieuDepart);
        	ldao.create(depart);
        }
        else
        	depart = ldao.getByName(lieuDepart);
        
        Lieu arrivee;
        if(!ldao.isExists(lieuArrivee)){
        	arrivee = new Lieu(lieuArrivee);
        	ldao.create(arrivee);
        }
        else
        	arrivee = ldao.getByName(lieuArrivee);
        
        s.flush();
        trx.commit();
        s.close();
        
		TrajetDAO trajetDao = dao.getTrajetDAO();
		
		s = HibernateUtil.getCurrentSession();
		trx = s.beginTransaction();
		
        Trajet trajet = new Trajet();
        
        trajet.setConducteur(c);
        trajet.setDepart(depart);
        trajet.setArrivee(arrivee);
        trajet.setPlaceRestantes(nbPlaceRestantes);
        trajet.setPrixPlace(prixPlace);
        trajet.setDateDepart(dateDepart);
        
        trajetDao.create(trajet);
        
        s.flush();
        trx.commit();
		s.close();
		
        return new TrajetTransfert(trajet);
	}

	@Override
	public List<ITrajet> rechercher(Date date, String lieuDepart) {
		
		TrajetDAO trajetDao = dao.getTrajetDAO();
		LieuDAO lieuDao = dao.getLieuDAO();
		
		Lieu depart = lieuDao.getByName(lieuDepart);
		
		List<Trajet> trajets = trajetDao.retreiveTrajetByDateAndLieuDepart(date, depart == null ? 0 : depart.getIdLieu());
		
		List<ITrajet> result = new ArrayList<ITrajet>();
		
		if(trajets != null)
			for(Trajet trajet:trajets)
				result.add(new TrajetTransfert(trajet));
		
		return result;
	}

	@Override
	public ITrajet souscrire(int idTrajet, int covoitureur) throws AlreadySubscribedException{
		
		ClientDAO cdao = dao.getClientDAO();
		Client c = cdao.get(new Long(covoitureur));
		
		if(c != null){
			
			TrajetDAO trajetDao = dao.getTrajetDAO();
			Trajet trajet = trajetDao.get(idTrajet);
			
			if(trajet != null){
				
				if(trajet.getCovoitureurs().size() < trajet.getPlaceRestantes()){
					
					Session s = HibernateUtil.getCurrentSession();
					Transaction trx = s.beginTransaction();
					
					trajet.getCovoitureurs().add(c);
					trajet.setPlaceRestantes((short) (trajet.getPlaceRestantes() - 1));
					
					try{
						trajetDao.update(trajet);
						s.flush();
						trx.commit();
						s.close();
					}
					catch (NonUniqueObjectException e) {
						throw new AlreadySubscribedException();
					}
					
					return new TrajetTransfert(trajet);
				}
			}
		}
		
		return null;
	}

	@Override
	public void deleteAll() {
		
		TrajetDAO trajetDao = dao.getTrajetDAO();
		trajetDao.deleteAll();
	}

}
